﻿using DevExpress.Data.Filtering;
using DevExpress.Mvvm.Gantt;
using DevWpfApp.ResourceManage;
using log4net;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace DevWpfApp
{
    /// <summary>
    /// LsGanttControl.xaml 的交互逻辑
    /// </summary>
    public partial class LsGanttControl : UserControl
    {
        public LsGanttControl()
        {
            InitializeComponent();
            data = new ProjectTaskViewModel();
            this.DataContext = data;
            UpdateTaskIdGenerator();
            UpdateResourceIdGenerator();
        }
        ProjectTaskViewModel data;

        public static ILog log = LogManager.GetLogger("LsGanttControl");


        string FilePath = string.Empty;
        private void SaveBtn_Click(object sender, RoutedEventArgs e)
        {
            if (FilePath == string.Empty)
            {
                SaveFileDialog dialog = new SaveFileDialog();
                if (dialog.ShowDialog() == true)
                {
                    FilePath = dialog.FileName;
                }
            }
            if (FilePath != string.Empty)
                data.Save(FilePath);

        }

        private void LoadBtn_Click(object sender, RoutedEventArgs e)
        {
            ShowAllTask();
            try
            {
                OpenFileDialog dialog = new OpenFileDialog();
                dialog.Filter = "*.txt|*.txt";
                if (dialog.ShowDialog() != true)
                    return;
                data.Load(dialog.FileName);
                FilePath = dialog.FileName;
                this.DataContext = null;
                this.DataContext = data;
                UpdateTaskIdGenerator();
                UpdateResourceIdGenerator();
                this.TaskCountTb.Text = data.CountTask().ToString();
                
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        private void UpdateTaskIdGenerator()
        {
            int id = 0;
            foreach (var t in data.Tasks)
                if ((int)t.Id > id)
                    id = (int)t.Id;
            IntIdGenerator.Current = id;
        }
        private void UpdateResourceIdGenerator()
        {
            int id = 0;
            foreach (var t in data.Resources)
                if ((int)t.Id > id)
                    id = (int)t.Id;
            ResourceIdGenerator.Current = id;
        }
        private void AddResourceBtn_Click(object sender, RoutedEventArgs e)
        {
            InputWindow win = new InputWindow();
            win.Title = "添加资源";
            win.DataName = "资源名称";
            if (win.ShowDialog() == true)
            {
                GanttResource resource = new GanttResource() { Id = ResourceIdGenerator.NewId(), Name = win.DataValue };
                data.Resources.Add(resource);
            }
        }

        private void SwitchResourceAndTaskNameBtn_Click(object sender, RoutedEventArgs e)
        {
            this.GanttView.UseResourcesAsTaskContent = !this.GanttView.UseResourcesAsTaskContent;
        }

        private void ResourceManageBtn_Click(object sender, RoutedEventArgs e)
        {
            ResourceManageWindow win = new ResourceManageWindow();
            win.GanttResources = data.Resources;
            win.ShowDialog();
            if(win.SelectedResource!=null)
            {
                ShowAllTask();
                foreach(var task in data.Tasks)
                {
                    foreach(var link in task.ResourceLinks)
                    {
                        if(link.ResourceId.Equals(win.SelectedResource.Id))
                        {
                            task.Name = task.Name + "：资源：";
                            break;
                        }
                    }
                }
                GanttControl.FilterString = "Contains([Name], '：资源：')";
            }
        }

        private void NewBtn_Click(object sender, RoutedEventArgs e)
        {
            if (MessageBox.Show("确认新建吗？", "确认", MessageBoxButton.YesNo, MessageBoxImage.Stop, MessageBoxResult.No) == MessageBoxResult.No)
                return;
            data = new ProjectTaskViewModel();
            data._password = "";
            this.DataContext = data;
            UpdateTaskIdGenerator();
            UpdateResourceIdGenerator();
        }

        private void ShowHasDoneBtn_Click(object sender, RoutedEventArgs e)
        {
            ShowAllTask();
            GanttControl.FilterCriteria = new BinaryOperator("Progress", 1, BinaryOperatorType.Equal);
            ShowHasDoneBtn.IsChecked = true;
        }

        private void ShowNotDoneBtn_Click(object sender, RoutedEventArgs e)
        {
            ShowAllTask();
            GanttControl.FilterCriteria = new BinaryOperator("Progress", 1, BinaryOperatorType.NotEqual);
            ShowNotDoneBtn.IsChecked = true;
        }

        private void ShowAllProgressBtn_Click(object sender, RoutedEventArgs e)
        {
            ShowAllTask();
            ShowAllProgressBtn.IsChecked = true;
        }


        private void NoDurationBtn_Click(object sender, RoutedEventArgs e)
        {
            ShowAllTask();
            GanttControl.FilterString = "[Duration] Is Null ";

        }

        private void NoStartDateBtn_Click(object sender, RoutedEventArgs e)
        {
            ShowAllTask();
            GanttControl.FilterString = "[StartDate] Is Null";
            NoStartDateBtn.IsChecked = true;
        }

        private void CurrentBtn_Click(object sender, RoutedEventArgs e)
        {
            ShowAllTask();
            GanttControl.FilterString = "Contains([Name], '当前：')";
            CurrentBtn.IsChecked = true;
        }

        private bool _isshowweek = false;
        private bool showweek2 = true;
        private void ThisWeekBtn_Click(object sender, RoutedEventArgs e)
        {
            if (_isshowweek == false)
            {
                showweek2 = false;
                ShowWeek();
            }
            else
            {
                ShowAllTask();
            }
            ThisWeekBtn.IsChecked = _isshowweek;
        }
        private void ShowWeek()
        {
            ShowAllTask();
            _isshowweek = true;
            DateTime startday = DateTime.Now.Date.AddDays(-(((int)DateTime.Now.DayOfWeek + 2) % 7));
            foreach (var task in data.Tasks)
            {
                if (task.StartDate.HasValue && task.FinishDate.HasValue
                       && task.StartDate.Value <= startday.AddDays(7)
                       && task.FinishDate.Value >= startday)
                    task.Name = "：本周：" + task.Name;

            }
            GanttControl.FilterString = "Contains([Name], '：本周：')";
        }

        private void ThisWeek2Btn_Click(object sender, RoutedEventArgs e)
        {
            if (_isshowweek == false)
            {
                showweek2 = true;
                ShowWeek2();
            }
            else
            {
                ShowAllTask();
            }
            ThisWeek2Btn.IsChecked = _isshowweek;
        }
        private void ShowWeek2()
        {
            ShowAllTask();
            _isshowweek = true;
            DateTime startday = DateTime.Now.Date.AddDays(-(((int)DateTime.Now.DayOfWeek + 6) % 7));
            foreach (var task in data.Tasks)
            {
                if (task.StartDate.HasValue && task.FinishDate.HasValue
                       && task.StartDate.Value <= startday.AddDays(7)
                       && task.FinishDate.Value >= startday)
                    task.Name = "：本周：" + task.Name;

            }
            GanttControl.FilterString = "Contains([Name], '：本周：')";
        }
        private void ClearWeek()
        {
            if (_isshowweek == true)
            {
                foreach (var task in data.Tasks)
                    task.Name = task.Name.Replace("：本周：", "");
            }
            _isshowweek = false;
        }

        private bool _isshowtoday = false;
        private void TodayTaskBtn_Click(object sender, RoutedEventArgs e)
        {
            if (_isshowtoday == false)
            {
                ShowToday();
            }
            else
            {
                ClearToday();
                GanttControl.FilterCriteria = null;
            }
            TodayTaskBtn.IsChecked = _isshowtoday;
        }
        private void ShowToday()
        {
            ShowAllTask();
            _isshowtoday = true;
            foreach (var task in data.Tasks)
            {
                if (task.StartDate.HasValue && task.FinishDate.HasValue
                       && task.StartDate.Value <= DateTime.Now.Date.AddDays(2)
                       && task.FinishDate.Value >= DateTime.Now.Date)
                    task.Name = "：今明：" + task.Name;

            }
            GanttControl.FilterString = "Contains([Name], '：今明：')";
        }
        private void ClearToday()
        {
            if (_isshowtoday == true)
            {
                foreach (var task in data.Tasks)
                    task.Name = task.Name.Replace("：今明：", "");
            }
            _isshowtoday = false;
        }

        private void ShowAllTask()
        {
            ClearToday();
            ClearWeek();
            ClearNoResource();
            ClearShowResource();
            GanttControl.FilterCriteria = null;

            NoResourceBtn.IsChecked = false;
            TodayTaskBtn.IsChecked = false;
            ThisWeek2Btn.IsChecked = false;
            ThisWeekBtn.IsChecked = false;
            NoStartDateBtn.IsChecked = false;
            CurrentBtn.IsChecked = false;
            ShowNotDoneBtn.IsChecked = false;
            ShowHasDoneBtn.IsChecked = false;
            ShowAllProgressBtn.IsChecked = false;
        }

        private bool _isshownoresource = false;
        private void NoResourceBtn_Click(object sender, RoutedEventArgs e)
        {
            if (_isshownoresource == false)
            {
                ShowNoResource();
            }
            else
            {
                ClearNoResource();
                GanttControl.FilterCriteria = null;
            }
            NoResourceBtn.IsChecked = _isshownoresource;
        }
        private bool IsNoResource(GanttTask task, ObservableCollection<GanttTask> tasks)
        {
            var children = (from t in tasks
                            where (t.ParentId != null && (int)t.ParentId == (int)task.Id)
                            select t).ToList();
            foreach (var c in children)
            {
                if (IsNoResource(c, tasks) == true)
                    return true;
            }
            if (children.Count() == 0)
                return task.ResourceLinks.Count == 0;
            else
                return false;
        }
        private void ShowNoResource()
        {
            ShowAllTask();
            _isshownoresource = true;
            data.UpdateId();
            foreach (var task in data.Tasks)
            {
                if (IsNoResource(task, data.Tasks))
                    task.Name = "：无资源：" + task.Name;

            }
            GanttControl.FilterString = "Contains([Name], '：无资源：')";
        }
        private void ClearShowResource()
        {
                foreach (var task in data.Tasks)
                    task.Name = task.Name.Replace("：资源：", "");
        }
        private void ClearNoResource()
        {
            if (_isshownoresource == true)
            {
                foreach (var task in data.Tasks)
                    task.Name = task.Name.Replace("：无资源：", "");
            }
            _isshownoresource = false;
        }


        #region 视图

        /// <summary>
        /// 添加任务后更新视图（默认GanttControl不主动更新）。
        /// </summary>
        private void UpdateView()
        {
            if (_isshowtoday)
            {
                ShowToday();
            }
            else if (_isshowweek)
            {
                if (showweek2)
                    ShowWeek2();
                else
                    ShowWeek();
            }
            else if (_isshownoresource)
            {
                ShowNoResource();
            }
        }

        #endregion

        #region 添加任务（易用性）

        private void SubTaskMi_Click(object sender, RoutedEventArgs e)
        {
            data.UpdateId();
            var task = (GanttControl.SelectedItem as GanttTask);
           var newtask= CreateSubTask(task, data.Tasks);
            UpdateView();
            this.GanttControl.SelectedItem = newtask;
        }
        private void NextTaskMi_Click(object sender, RoutedEventArgs e)
        {
            data.UpdateId();
            var task = (GanttControl.SelectedItem as GanttTask);
            var newtask = CreateNextTask(task, data.Tasks);
            UpdateView();
            this.GanttControl.SelectedItem = newtask;
        }
        private void PreTaskMi_Click(object sender, RoutedEventArgs e)
        {
            data.UpdateId();
            var task = (GanttControl.SelectedItem as GanttTask);
            var newtask = CreatePreTask(task, data.Tasks);
            UpdateView();
            this.GanttControl.SelectedItem = newtask;
        }

        private static GanttTask CreateSubTask(GanttTask task, ObservableCollection<GanttTask> tasks)
        {
            if (task == null)
                return null;
            var taskindex = tasks.IndexOf(task);
            if (taskindex == -1)
                return null;
            var subtask = new GanttTask { Id = IntIdGenerator.NewId(), Name = "新任务", ParentId = task.Id, StartDate = task.StartDate, FinishDate = task.FinishDate };
            if (taskindex == tasks.Count - 1)
                tasks.Add(subtask);
            else
                tasks.Insert(taskindex + 1, subtask);
            return subtask;
        }
        private static GanttTask CreateNextTask(GanttTask task, ObservableCollection<GanttTask> tasks)
        {
            if (task == null)
                return null;
            var taskindex = tasks.IndexOf(task);
            if (taskindex == -1)
                return null;
            var nexttask = new GanttTask { Id = IntIdGenerator.NewId(), Name = "新任务", ParentId = task.ParentId, StartDate = task.StartDate, FinishDate = task.FinishDate };
            if (taskindex == tasks.Count - 1)
                tasks.Add(nexttask);
            else
                tasks.Insert(taskindex + 1, nexttask);
            return nexttask;
        }
        private static GanttTask CreatePreTask(GanttTask task, ObservableCollection<GanttTask> tasks)
        {
            if (task == null)
                return null;
            var taskindex = tasks.IndexOf(task);
            if (taskindex == -1)
                return null;
            var pretask = new GanttTask { Id = IntIdGenerator.NewId(), Name = "新任务", ParentId = task.ParentId, StartDate = task.StartDate, FinishDate = task.FinishDate };
            tasks.Insert(taskindex, pretask);
            return pretask;
        }

        #endregion

    }
}
